import { _decorator, Button, Component, Node, tween, Vec3 } from 'cc';
import { Card } from '../Card';
import { TableauPile } from '../TableauPile';
import EventManager, { EVENT_ENUM } from './EventManager';
import { UIManager } from './UIManager';
import { Global } from '../Global';
import { Constant } from '../Constant';
import { Util } from '../Util/Util';
const { ccclass, property } = _decorator;

@ccclass('GameManager')
export class GameManager extends Component {
    @property(Node)
    drawnPile: Node = null;
    @property(Node)
    stockPile: Node = null;
    @property([Node])
    tableauPiles: Node[] = [];
    @property([Node])
    foundationPiles: Node[] = [];

    private drawnCards: Node[] = [];
    private cardOffsetX: number = 100; // 卡牌之间的水平偏移量
    private cardOffsetY: number = 30;  // 卡牌之间的垂直偏移量
    private drawnCardRows: number = 0; // 当前已绘制的行数

    private historyStack: Array<{ card: Node, fromPile: Node, toPile: Node, originalPosition: Vec3 }> = [];

    onLoad() {
        Global.init().then(() => {
            Constant.ndUI = Util.createSubNode('UILayer', this.node.parent);
        });
        EventManager.on(EVENT_ENUM.DRAW_CARDS, this.drawCards, this);
        EventManager.on(EVENT_ENUM.UNDO, this.undo, this);
        EventManager.on(EVENT_ENUM.DISTURB, this.disturbCards, this);
    }

    protected start(): void {
        this.drawCards();
    }

    protected onDestroy(): void {
        EventManager.off(EVENT_ENUM.DRAW_CARDS, this.drawCards);
        EventManager.off(EVENT_ENUM.UNDO, this.undo);
        EventManager.off(EVENT_ENUM.DISTURB, this.disturbCards);

    }

    /**发牌 */
    private drawCards() {
        const stockCards = this.stockPile.children;
        if (stockCards.length === 0) return;
        if (this.drawnCardRows >= 4) {
            this.drawnCardRows = 4;
        } else {
            this.cardOffsetY = Math.max(5, this.cardOffsetY - 5);
        }

        let rowPosition = this.drawnCardRows * this.cardOffsetY;

        for (let i = 0; i < 3 && stockCards.length > 0; i++) {
            const card = stockCards[stockCards.length - 1];
            this.stockPile.removeChild(card);
            this.drawnPile.addChild(card);

            const position = new Vec3(i * this.cardOffsetX, -rowPosition, 0);
            const cardComp = card.getComponent(Card)!;

            cardComp.moveTo(position, 0.2, () => {
                cardComp.flip();
                card.on(Node.EventType.TOUCH_END, () => {
                    this.tryPlaceCard(card);
                }, this);
            });

            this.drawnCards.push(card);
        }
        this.drawnCardRows++;
    }

    private tryPlaceCard(card: Node) {
        const cardComp = card.getComponent(Card)!;
        let fromPile: Node | null = null;

        const placedInFoundation = this.tryPlaceInFoundation(card, cardComp);
        if (placedInFoundation) {
            fromPile = card.parent!;
        } else {
            const placedInTableau = this.tryPlaceInTableau(cardComp);
            if (placedInTableau) {
                fromPile = card.parent!;
            }
        }

        if (fromPile) {
            this.historyStack.push({
                card, fromPile, toPile: card.parent!,
                originalPosition: card.position.clone()
            });
            this.checkAutoMove();
        }
    }

    private tryPlaceInFoundation(card: Node, cardComp: Card): boolean {
        for (let foundation of this.foundationPiles) {
            const topCard = foundation.children[foundation.children.length - 1]?.getComponent(Card);
            if (topCard) {
                if (topCard.suit === cardComp.suit && topCard.rank === cardComp.rank - 1) {
                    foundation.addChild(card);
                    card.setPosition(Vec3.ZERO);
                    return true;
                }
            } else if (cardComp.rank === 1) {
                foundation.addChild(card);
                card.setPosition(Vec3.ZERO);
                return true;
            }
        }
        return false;
    }

    private tryPlaceInTableau(cardComp: Card): boolean {
        for (let pile of this.tableauPiles) {
            const pileComp = pile.getComponent(TableauPile);
            if (pileComp && pileComp.getCardCount() === 0) {
                pileComp.addCard(cardComp);
                return true;
            } else if (pileComp && pileComp.getCardCount() > 0 && pileComp.canDropCard(cardComp)) {
                pileComp.addCard(cardComp);
                return true;
            }
        }
        return false;
    }


    /*撤销操作*/
    public undo() {
        if (this.historyStack.length === 0) {
            console.log("没有可以撤销的操作");
            return;
        }

        const lastAction = this.historyStack.pop();
        if (!lastAction) return;
        const { card, fromPile, toPile, originalPosition } = lastAction;
        toPile.removeChild(card);
        if (fromPile.getComponent(TableauPile)) {
            const pileComp = fromPile.getComponent(TableauPile);
            pileComp?.addCard(card.getComponent(Card)!);
        } else {
            fromPile.addChild(card);
            card.setPosition(this.getCardPositionInPile(fromPile));
        }
        card.setPosition(originalPosition);
    }


    private getCardPositionInPile(pile: Node): Vec3 {
        const spacingY = -30;
        const index = pile.children.length - 1;
        return new Vec3(0, spacingY * index, 0);
    }

    update(deltaTime: number) {

    }

    /**打乱纸牌 */
    private disturbCards() {
        const cards = this.drawnPile.children.slice();
        for (let i = cards.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));

            const tempPos = cards[i].position.clone();
            cards[i].setPosition(cards[j].position);
            cards[j].setPosition(tempPos);

            this.drawnPile.insertChild(cards[i], j);
            this.drawnPile.insertChild(cards[j], i);
        }
    }

    //判断游戏胜利条件
    private checkWinCondition(): boolean {
        for (const foundation of this.foundationPiles) {
            if (!this.isFoundationComplete(foundation)) {
                return false;
            }
        }
        return true;
    }

    private isFoundationComplete(foundation: Node): boolean {
        const cards = foundation.children;
        if (cards.length !== 13) return false;

        const firstCard = cards[0].getComponent(Card)!;
        let expectedRank = 1;

        for (const cardNode of cards) {
            const card = cardNode.getComponent(Card)!;
            if (card.suit !== firstCard.suit || card.rank !== expectedRank) {
                return false;
            }
            expectedRank++;
        }
        return true;
    }

    private checkAutoMove() {
        for (const pile of this.tableauPiles) {
            const pileComp = pile.getComponent(TableauPile);
            if (pileComp) {
                const topCard = pileComp.topCard;
                if (topCard) {
                    this.tryMoveToFoundation(topCard.node, pileComp);
                }
            }
        }
    }

    private tryMoveToFoundation(cardNode: Node, sourcePile: TableauPile) {
        const cardComp = cardNode.getComponent(Card)!;

        for (const foundation of this.foundationPiles) {
            const topFoundationCard = foundation.children[foundation.children.length - 1]?.getComponent(Card);
            if (!topFoundationCard) {
                if (cardComp.rank === 1) {
                    this.moveCardToFoundation(cardNode, sourcePile, foundation);
                    return true;
                }
                continue;
            }
            if (topFoundationCard.suit === cardComp.suit &&
                topFoundationCard.rank === cardComp.rank - 1) {
                this.moveCardToFoundation(cardNode, sourcePile, foundation);
                return true;
            }
        }
        return false;
    }


    private moveCardToFoundation(cardNode: Node, sourcePile: TableauPile, foundation: Node) {
        const cardComp = cardNode.getComponent(Card)!;

        const removedCard = sourcePile.removeTopCard();
        if (!removedCard) return;

        removedCard.removeFromParent();

        const targetPos = foundation.position;

        this.node.addChild(removedCard);

        let preTableauPile = cardComp.tableauPile;
        if (preTableauPile != null && preTableauPile.bottomCard != null && preTableauPile.bottomCard == cardComp) {
            preTableauPile.bottomCard = null;
        }
        if (preTableauPile) {
            preTableauPile.topCard = cardComp.preCard;

        }
        cardComp.preCard?.setNextCard(null);
        cardComp.setPreCard(null);
        preTableauPile = null;


        cardComp.moveTo(targetPos, 0.2, () => {
            foundation.addChild(removedCard);
            removedCard.setPosition(Vec3.ZERO);

            this.checkAutoMove();
            if (this.checkWinCondition()) {
                UIManager.instance.showUI('GAME_WIN_UI');
                console.log("游戏胜利！");
            }
        });
    }
}
